using System;
using System.Collections.Generic;
using SCG.SolarVengeanceEngine;
using SCG.SolarVengeanceEngine.BrainInfo;
using System.Windows;
using System.Drawing;

namespace SCG.SolarVengeance.Brains
{
    //Organism v1.0.1
    //Organism's script is 1200 lines long.
    /*
    01/03/2009: Start of Organism
    02/10/2009: v1.0.0: Initial Release
    02/16/2009: v1.0.1: Fixed a minor bug with alliances and also added the capability 
      for multiple organisms to ally with each other. Also made organism cloak its 
      techships when it begins to cloak to prevent opponents from spotting them with scanners.
      
     
    */

    public class Organism : Brain
    {
        #region Overrides and Private Variables
        private List<string> mmMessage = new List<string>();
        private List<string> mmSentByPlayer = new List<string>();

        public override ChallengeLevel Challenge
        {
            get
            {
                return ChallengeLevel.Extreme;
            }
        }

        public override string Author
        {
            get
            {
                return "Beat2k";
            }
        }

        public override string Description
        {
            get
            {
                return "1/03/09 V1.0.1 Organism. CLASSIFIED MODEL 2009A-- Organism, built completely from scratch, has the ability to ally with and work with players. " + 
                       "Organism is designed to work in the exotic scenarios including scenarios with only starships!";
            }
        }

        public override List<StarShipType> AvailableShipTypes
        {
            get
            {
                List<StarShipType> avail = new List<StarShipType>();
                avail.Add(StarShipType.WarShip);
                avail.Add(StarShipType.EMine);
                avail.Add(StarShipType.Drone);
                avail.Add(StarShipType.HijackShip);
                avail.Add(StarShipType.CommandShip);
                avail.Add(StarShipType.TechShip);
                return avail;
            }
        }

        public override void IncomingMessage(string playerName, string message)
        {
            mmMessage.Add(message);
            mmSentByPlayer.Add(playerName);
        }

        private Dictionary<string, bool> ssDangerStar = new Dictionary<string, bool>();
        private Dictionary<string, int> ssLastStarOwner = new Dictionary<string, int>();
        private Dictionary<string, int> ssStarValue = new Dictionary<string, int>();
        private Dictionary<string, int> ssLastKnownShields = new Dictionary<string, int>();
        private Dictionary<string, StarSystemInfo> ShipStarTarget = new Dictionary<string, StarSystemInfo>();
        private Point centerofuniverse = new Point(-1,-1);
        private List<StarSystemInfo> ssECapital = new List<StarSystemInfo>();
        private int msgstate = 0;
        private string msgreceiver = "";
        private bool[] justallied = new bool[10] { false, false, false, false, false, false, false, false, false, false };
        #endregion

        public override void Execute()
        {
            //string debugstring = "";
            try
            {
                //debugstring = "Error : Intelligence And Alliances";
                #region Intelligence And Alliances
                int numplayers = PlayerNames.Count;
                int alliedplayers = 0;
                for (int d = 0; d < PlayerNames.Count; d++)
                {
                    if (PlayerNames[d] != Name)
                    {
                        if (IsFullAlliance(PlayerNames[d]) == true)
                            alliedplayers++;
                    }
                    else
                    {
                        //count myself as an allied player
                        alliedplayers++;
                    }
                }
                //read messages from other players
                List<string> word = new List<string>();
                string bugmessage = "";
                bool addressed = false;
                for (int d = 0; d < mmMessage.Count; d++)
                {
                    bugmessage = mmMessage[d].ToLower();
                    BreakDownMessageIntoWords(bugmessage, word);
                    addressed = IsMessageAdressedToMe(Name, bugmessage);
                    if (addressed == true)
                    {
                        bugmessage = bugmessage.Substring(Name.Length + 2, bugmessage.Length - (Name.Length + 2));
                        if ((bugmessage == "alliance?") | (bugmessage == "ally with me?") | (bugmessage == "do you want to ally with me?") | (bugmessage == "ally?"))
                        {
                            if (alliedplayers < (int)Math.Round((double)numplayers / 2.0))
                            {
                                //Accept alliances from other players.
                                SendMessage(ChatChannel.All, "Yes");
                                SetAlliance(mmSentByPlayer[d], AllianceLevel.Formal);
                                AllianceSet(mmSentByPlayer[d]);
                                msgstate = 0;
                                msgreceiver = "";
                            }
                            else
                            {
                                SendMessage(ChatChannel.All, "No");
                            }
                        }
                        else if (msgstate == 1)
                        {
                            if (msgreceiver == mmSentByPlayer[d])
                            {
                                if (IsPositive(bugmessage) == true)
                                {
                                    SetAlliance(mmSentByPlayer[d], AllianceLevel.Formal);
                                    AllianceSet(mmSentByPlayer[d]);
                                    msgstate = 0;
                                }
                                else if (IsNegative(bugmessage) == true)
                                {
                                    msgstate = 2;
                                }
                            }
                        }
                    }
                    else
                    {
                        if ((bugmessage == "alliance?") | (bugmessage == "ally with me?") | (bugmessage == "do you want to ally with me?") | (bugmessage == "ally?"))
                        {
                            if (alliedplayers < (int)Math.Round((double)numplayers / 2.0))
                            {
                                //Accept alliances from other players.
                                SendMessage(ChatChannel.All, "Yes");
                                SetAlliance(mmSentByPlayer[d], AllianceLevel.Formal);
                                AllianceSet(mmSentByPlayer[d]);
                                msgstate = 0;
                                msgreceiver = "";
                            }
                            else
                            {
                                SendMessage(ChatChannel.All, "No");
                            }
                        }
                        else if (msgstate == 1)
                        {
                            if (msgreceiver == mmSentByPlayer[d])
                            {
                                if (IsPositive(bugmessage) == true)
                                {
                                    SetAlliance(mmSentByPlayer[d], AllianceLevel.Formal);
                                    AllianceSet(mmSentByPlayer[d]);
                                    msgstate = 0;
                                }
                                else if (IsNegative(bugmessage) == true)
                                {
                                    msgstate = 2;
                                }
                            }
                        }
                    }
                }

                //Change alliance status for any player allied with it.
                for (int d = 0; d < PlayerNames.Count; d++)
                {
                    if (PlayerNames[d] != Name)
                    {
                        if (IsFullAlliance(PlayerNames[d]) == true)
                        {
                            if (AlliedWith(PlayerNames[d]) != AlliedWithMe(PlayerNames[d]))
                            {
                                SetAlliance(PlayerNames[d], AlliedWithMe(PlayerNames[d]));
                            }
                            if (numplayers <= alliedplayers + 1)
                            {
                                if (AlliedWith(PlayerNames[d]) != AllianceLevel.Formal)
                                {
                                    SetAlliance(PlayerNames[d], AllianceLevel.None);
                                    AllianceBroke(PlayerNames[d]);
                                }
                            }
                        }
                        else
                        {
                            if (AlliedWith(PlayerNames[d]) != AllianceLevel.None)
                            {
                                SetAlliance(PlayerNames[d], AllianceLevel.None);
                                AllianceBroke(PlayerNames[d]);
                            }
                            if (AlliedWithMe(PlayerNames[d]) != AllianceLevel.None)
                            {
                                if (alliedplayers < (int)Math.Round((double)numplayers / 2.0))
                                {
                                    SetAlliance(PlayerNames[d], AlliedWithMe(PlayerNames[d]));
                                    AllianceSet(PlayerNames[d]);
                                }
                            }
                        }
                    }
                }
                //erase previous messages
                mmMessage.Clear();
                mmSentByPlayer.Clear();

                //create engine variables
                int wareng1 = 2 + (int)(TechMultiple / 3.0);
                int wareng2 = 6 + (int)(TechMultiple / 2.0);
                int wareng3 = 8 + (int)(TechMultiple);
                int wareng4 = 11 + (int)(TechMultiple);
                if (wareng1 > 20) wareng1 = 20;
                if (wareng2 > 20) wareng2 = 20;
                if (wareng3 > 20) wareng3 = 20;
                if (wareng4 > 20) wareng4 = 20;
                bool cloaker = false;
                if (TechMultiple >= 6) cloaker = true;

                #endregion
                //debugstring = "Error : Starship Sorter";
                #region StarShip Sorter and Analyzer
                Dictionary<int, StarShipInfo> uuWarShip = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuCommandShip = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuHijackShip = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuTechShip = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuEMine = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuStarTillery = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuOther = new Dictionary<int, StarShipInfo>();
                Dictionary<int, StarShipInfo> uuEnemyStarship = new Dictionary<int, StarShipInfo>();

                StarShipInfo ship;
                for (int d = 0; d < StarShips.Count; d++)
                {
                    ship = StarShips[d];
                    if (ship.OwnedByMe == true)
                    {
                        if (ship.ShipType == StarShipType.WarShip) uuWarShip.Add(uuWarShip.Count, ship);
                        else if (ship.ShipType == StarShipType.CommandShip) uuCommandShip.Add(uuCommandShip.Count, ship);
                        else if (ship.ShipType == StarShipType.HijackShip) uuHijackShip.Add(uuHijackShip.Count, ship);
                        else if (ship.ShipType == StarShipType.EMine) uuEMine.Add(uuEMine.Count, ship);
                        else if (ship.ShipType == StarShipType.StarTillery) uuStarTillery.Add(uuStarTillery.Count, ship);
                        else if (ship.ShipType == StarShipType.TechShip) uuTechShip.Add(uuTechShip.Count, ship);
                        else uuOther.Add(uuOther.Count, ship);
                    }
                    else
                    {
                        if (IsFullAlliance(ship.Owner) == false)
                            uuEnemyStarship.Add(uuEnemyStarship.Count, ship);
                    }
                }

                #endregion
                //debugstring = "Error : StarSystem Sorter";
                #region StarSystem Sorter and Analyzer
                Dictionary<int, StarSystemInfo> ssMyStarSystem = new Dictionary<int, StarSystemInfo>();
                Dictionary<int, StarSystemInfo> ssTeamStarSystem = new Dictionary<int, StarSystemInfo>();
                Dictionary<string, int> ssTShields = new Dictionary<string, int>();
                Dictionary<string, int> ssMelees = new Dictionary<string, int>();
                Dictionary<int, StarSystemInfo> ssTarget = new Dictionary<int, StarSystemInfo>();

                StarSystemInfo sys = null;
                StarSystemInfo mycap = null;
                int cooraddx = 0;
                int cooraddy = 0;
                int knownstarshields = 0;
                int knownstars = 0;
                bool closecombatbattle = false;
                for (int d = 0; d < StarSystems.Count; d++)
                {
                    sys = StarSystems[d];
                    if ((centerofuniverse.X == -1) & (centerofuniverse.Y == -1))
                    {
                        cooraddx = cooraddx + sys.X;
                        cooraddy = cooraddy + sys.Y;
                    }
                    if (ssLastStarOwner.ContainsKey(sys.Name) == false) ssLastStarOwner.Add(sys.Name, -2);
                    if (ssLastKnownShields.ContainsKey(sys.Name) == false) ssLastKnownShields.Add(sys.Name, 999);
                    if (ssStarValue.ContainsKey(sys.Name) == false) ssStarValue.Add(sys.Name, 0);
                    if (ssMelees.ContainsKey(sys.Name) == false) ssMelees.Add(sys.Name, 0);
                    if (ssTShields.ContainsKey(sys.Name) == false) ssTShields.Add(sys.Name, 999);
                    if (ssDangerStar.ContainsKey(sys.Name) == false) ssDangerStar.Add(sys.Name, false);
                    if (sys.OwnedByMe == true)
                    {
                        ssMyStarSystem.Add(ssMyStarSystem.Count, sys);
                        ssTeamStarSystem.Add(ssTeamStarSystem.Count, sys);
                        if (sys.IsCapital == true)
                            mycap = sys;
                    }
                    else
                    {
                        if (sys.Visible == true)
                        {
                            ssLastKnownShields[sys.Name] = sys.Shields;
                            ssLastStarOwner[sys.Name] = sys.OwnerInt;
                            ssStarValue[sys.Name] = (sys.Value + (sys.Resources / 5) + (sys.Scanners / 5)) - (sys.Shields / 2);
                            if (sys.OwnerInt > -1)
                            {
                                ssDangerStar[sys.Name] = true;
                                if (sys.IsCapital == true)
                                    if (ssECapital.Contains(sys) == false)
                                        ssECapital.Add(sys);
                            }
                        }
                        else
                        {
                            if (ssLastStarOwner[sys.Name] >= 0)
                                ssLastKnownShields[sys.Name] = 25;
                        }
                        ssTShields[sys.Name] = ssLastKnownShields[sys.Name];

                        if (sys.OwnerInt > -1)
                        {
                            if (IsFullAlliance(sys.Owner) == false)
                            {
                                ssTarget.Add(ssTarget.Count, sys);
                            }
                            else
                            {
                                ssTeamStarSystem.Add(ssTeamStarSystem.Count, sys);
                            }
                        }
                        else
                        {
                            ssTarget.Add(ssTarget.Count, sys);
                        }
                    }
                }

                if ((centerofuniverse.X == -1) & (centerofuniverse.Y == -1))
                {
                    centerofuniverse.X = (int)(cooraddx / StarSystems.Count);
                    centerofuniverse.Y = (int)(cooraddy / StarSystems.Count);
                }

                if (mycap != null)
                {
                    foreach (StarSystemInfo sys2 in StarSystems)
                        if (sys2.OwnedByMe == false)
                            if (Distance(sys2.X, sys2.Y, mycap.X, mycap.Y) <= 12)
                            {
                                knownstars++;
                                if (sys2.Visible == true)
                                    knownstarshields = knownstarshields + sys2.Shields;
                                else
                                    knownstarshields = knownstarshields + 20;
                            }
                }

                bool expand = false;
                expand = ((ssTeamStarSystem.Count < 8) | (ssTeamStarSystem.Count < StarSystems.Count / 10));

                //process enemy capitals
                StarSystemInfo ecap = null;
                //bool SE = false;
                bool passed = false;
                int ecapdist = 32767;
                for (int d = ssECapital.Count - 1; d >= 0; d--)
                {
                    sys = ssECapital[d];
                    passed = false;
                    if (sys.Visible == true)
                        if (sys.IsCapital == true)
                            passed = true;

                    if (passed == true)
                    {
                        if ((alliedplayers < (int)Math.Round((double)numplayers / 2.0)) & (numplayers > 2) & (msgstate == 0))
                        {
                            if (sys.Visible == true)
                            {
                                if ((AlliedWithMe(sys.Owner) == AllianceLevel.None) & (justallied[sys.OwnerInt] == false))
                                {
                                    msgstate = 1;
                                    msgreceiver = sys.Owner;
                                    SendMessage(ChatChannel.All, msgreceiver + ", Ally with me?");
                                }
                            }
                        }
                        //SE = true;
                        if (DistanceQuick(sys.X, sys.Y, mycap.X, mycap.Y) < ecapdist)
                        {
                            ecapdist = DistanceQuick(sys.X, sys.Y, mycap.X, mycap.Y);
                            ecap = sys;
                        }
                    }
                    else
                    {
                        ssECapital.Remove(sys);
                    }
                }
                if (ecapdist <= 10) closecombatbattle = true;

                #endregion
                //debugstring = "Error : Order Starships";
                #region Order Starships
                ship = null;
                bool zerostars = false;
                if (StarSystems.Count == 0) zerostars = true;
                StarSystemInfo sstarget = null;
                StarShipInfo shtarget = null;
                StarSystemInfo[] expsys = new StarSystemInfo[3];
                int[] expval = new int[3];
                int sysval = 0;
                int meleerange = 0;
                Point fleetpoint = new Point(0,0);

                sstarget = ClosestStarSystem(50, 50, 32767, FindSystemFlags.Unfriendly);
                if ((zerostars == true) | (sstarget == null))
                {
                    fleetpoint = new Point(Random(4, MapWidth - 5), Random(4, MapHeight - 5));
                }

                for (int d = 0; d < MyStarShips.Count; d++)
                {
                    ship = MyStarShips[d];
                    //My Warships
                    #region Warship Order Code
                    if ((ship.ShipType == StarShipType.WarShip) | (ship.ShipType == StarShipType.DoppleShip) | (ship.ShipType == StarShipType.BattleStation) | (ship.ShipType == StarShipType.Elite))
                    {
                        AttackAdjacent(ship, true);
                        sstarget = ClosestStarSystem(ship.X, ship.Y, 32767, FindSystemFlags.Unfriendly);
                        if ((zerostars == false) & (sstarget != null))
                        {
                            if (ShipStarTarget.ContainsKey(ship.Code) == false)
                            {
                                ShipStarTarget.Add(ship.Code, null);
                            }
                            else
                            {
                                sstarget = ShipStarTarget[ship.Code];
                                if (sstarget != null)
                                    if ((sstarget.OwnedByMe == true) | (IsFullAlliance(sstarget.Owner) == true))
                                        ShipStarTarget[ship.Code] = null;
                            }
                            if (ShipStarTarget[ship.Code] == null)
                            {
                                for (int ad = 0; ad < 3; ad++)
                                {
                                    expsys[ad] = null;
                                    expval[ad] = 0;
                                }
                                if (expand == true)
                                {
                                    for (int ad = 0; ad < ssTarget.Count; ad++)
                                    {
                                        sys = ssTarget[ad];
                                        sysval = ssStarValue[sys.Name];
                                        if ((ssLastStarOwner[sys.Name] < 0) & (ssTShields[sys.Name] > 0 - (int)(TechMultiple)))
                                        {
                                            if (expval[0] < sysval)
                                            {
                                                expval[0] = sysval;
                                                expsys[0] = sys;
                                            }
                                        }
                                    }
                                }
                                sstarget = expsys[0];
                                if (sstarget == null) sstarget = expsys[1];
                                if (sstarget == null) sstarget = expsys[2];
                                if (sstarget == null) sstarget = ClosestStarSystem(ship.X, ship.Y, 32767, FindSystemFlags.Unfriendly);
                                if (sstarget != null)
                                {
                                    Target(ship, sstarget);
                                    ShipStarTarget[ship.Code] = sstarget;
                                    ssTShields[sstarget.Name] = ssTShields[sstarget.Name] - ship.Value;
                                }
                            }
                            else
                            {
                                sstarget = ShipStarTarget[ship.Code];
                                sys = ClosestStarSystem(ship.X, ship.Y, 3, FindSystemFlags.Unfriendly);
                                if (sys != null) sstarget = sys;
                                Target(ship, sstarget);
                                ShipStarTarget[ship.Code] = sstarget;
                                ssTShields[sstarget.Name] = ssTShields[sstarget.Name] - ship.Value;
                                if (IsAdjacentToCoords(ship, sstarget.X, sstarget.Y) == true)
                                    AttackAdjacent(ship, false);
                            }
                        }
                        else
                        {
                            //Fleet wars!
                            shtarget = ClosestStarShip(ship.X, ship.Y, 32767, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            if (shtarget != null)
                            {
                                Move(ship, shtarget.X, shtarget.Y);
                            }
                            else
                            {
                                Move(ship, (int)fleetpoint.X, (int)fleetpoint.Y);
                            }
                        }
                    }
                    #endregion

                    //My Hijackships
                    #region Hijackship Order Code
                    if ((ship.ShipType == StarShipType.HijackShip) | (ship.ShipType == StarShipType.Drone) | (ship.ShipType == StarShipType.InkSpot))
                    {
                        shtarget = ClosestStarShip(ship.X, ship.Y, (ship.Engines / 2) + 3, FindShipFlags.Enemy, ShipKnownFlags.Either);
                        sstarget = ClosestStarSystem(ship.X, ship.Y, 32767, FindSystemFlags.Unfriendly);
                        AttackAdjacent(ship, true);
                        if (shtarget != null)
                        {
                            Move(ship, shtarget.X, shtarget.Y);
                        }
                        else if ((zerostars == false) & (sstarget != null))
                        {
                            if (uuHijackShip.Count < ssTeamStarSystem.Count * 8)
                            {
                                //defend my stars or allied stars
                                expval[0] = 32768;
                                expsys[0] = null;
                                for (int ad = 0; ad < ssTeamStarSystem.Count; ad++)
                                {
                                    sys = ssTeamStarSystem[ad];
                                    sysval = DistanceQuick(sstarget.X, sstarget.Y, sys.X, sys.Y);
                                    if (sysval < expval[0])
                                    {
                                        expsys[0] = sys;
                                        expval[0] = sysval;
                                    }
                                }
                                if (expsys[0] != null)
                                {
                                    ssMelees[expsys[0].Name]++;
                                    meleerange = 2 + (ssMelees[expsys[0].Name] / 8);
                                    Move(ship, expsys[0].X + Random(-meleerange, meleerange), expsys[0].Y + Random(-meleerange, meleerange));
                                }
                            }
                            else
                            {
                                //attack enemy starsystems
                                ssMelees[sstarget.Name]++;
                                meleerange = 2 + (ssMelees[sstarget.Name] / 8);
                                Move(ship, sstarget.X + Random(-meleerange, meleerange), sstarget.Y + Random(-meleerange, meleerange));
                            }
                        }
                        else
                        {
                            //Fleet Wars!
                            Move(ship, (int)fleetpoint.X, (int)fleetpoint.Y);
                        }
                    }
                    #endregion

                    //My E-Mine Order Code
                    #region E-mine Order Code
                    if (ship.ShipType == StarShipType.EMine)
                    {
                        shtarget = ClosestStarShip(ship.X, ship.Y, 10, FindShipFlags.Enemy, ShipKnownFlags.Either);
                        sstarget = ClosestStarSystem(ship.X, ship.Y, 32767, FindSystemFlags.Unfriendly);
                        if (shtarget != null)
                        {
                            Move(ship, shtarget.X, shtarget.Y);
                        }
                        else if ((zerostars == false) & (sstarget != null))
                        {
                            //defend my stars or allied stars
                            expval[0] = 32768;
                            expsys[0] = null;
                            for (int ad = 0; ad < ssTeamStarSystem.Count; ad++)
                            {
                                sys = ssTeamStarSystem[ad];
                                sysval = DistanceQuick(ship.X, ship.Y, sys.X, sys.Y);
                                if (sysval < expval[0])
                                {
                                    expsys[0] = sys;
                                    expval[0] = sysval;
                                }
                            }
                            if (expsys[0] != null)
                            {
                                ssMelees[expsys[0].Name]++;
                                meleerange = 1 + (ssMelees[expsys[0].Name] / 5);
                                Move(ship, expsys[0].X + Random(-meleerange, meleerange), expsys[0].Y + Random(-meleerange, meleerange));
                            }
                        }
                        else
                        {
                            //Fleet Wars!
                            Move(ship, (int)fleetpoint.X, (int)fleetpoint.Y);
                        }
                    }
                    #endregion

                    //My Techship Order Code
                    #region Techship Order Code
                    if ((ship.ShipType == StarShipType.TechShip) | (ship.ShipType == StarShipType.RemoteViewer))
                    {
                        shtarget = ClosestStarShip(ship.X, ship.Y, 20, FindShipFlags.Enemy, ShipKnownFlags.Either);
                        //Keep techships from going into known blackholes!
                        BlackHoleInfo bhtarget = null;
                        int bhdist = 20;
                        for (int ad = 0; ad < BlackHoles.Count; ad++)
                        {
                            if (DistanceQuick(BlackHoles[ad].X, BlackHoles[ad].Y, ship.X, ship.Y) <= bhdist)
                            {
                                bhdist = DistanceQuick(BlackHoles[ad].X, BlackHoles[ad].Y, ship.X, ship.Y);
                                bhtarget = BlackHoles[ad];
                            }
                        }
                        if (bhtarget != null)
                        {
                            Move(ship, bhtarget.X + (ship.X - bhtarget.X) * 2, bhtarget.Y + (ship.Y - bhtarget.Y) * 2);
                        }
                        else if (shtarget != null)
                        {
                            Move(ship, shtarget.X + (ship.X - shtarget.X) * 2, shtarget.Y + (ship.Y - shtarget.Y) * 2);
                        }
                        else
                        {
                            if (ship.X < centerofuniverse.X) expval[0] = 0;
                            else expval[0] = 1;
                            if (ship.Y < centerofuniverse.Y) expval[1] = 0;
                            else expval[1] = 1;
                            Move(ship, (MapWidth - 1) * expval[0], (MapHeight - 1) * expval[1]);
                        }
                    }
                    #endregion

                    //My Commandship Order Code
                    #region Commandship Order Code
                    if ((ship.ShipType == StarShipType.CommandShip) | (ship.ShipType == StarShipType.BeamShip) | (ship.ShipType == StarShipType.CloakDetector) | (ship.ShipType == StarShipType.ParalyShip))
                    {
                        sstarget = ClosestStarSystem(ship.X, ship.Y, 32767, FindSystemFlags.Unfriendly);
                        PulsarInfo pm = null;
                        if (ship.IsDamaged == true)
                        {
                            pm = ClosestPulsar(ship.X, ship.Y, 32767);
                        }

                        if (pm != null)
                        {
                            Move(ship, pm.X, pm.Y);
                        }
                        else if ((zerostars == false) & (sstarget != null))
                        {
                            //defend my stars or allied stars
                            expval[0] = 32768;
                            expsys[0] = null;
                            for (int ad = 0; ad < ssTeamStarSystem.Count; ad++)
                            {
                                sys = ssTeamStarSystem[ad];
                                sysval = DistanceQuick(sstarget.X, sstarget.Y, sys.X, sys.Y);
                                if (sysval < expval[0])
                                {
                                    expsys[0] = sys;
                                    expval[0] = sysval;
                                }
                            }
                            if (expsys[0] != null)
                            {
                                ssMelees[expsys[0].Name]++;
                                meleerange = (ship.Value / 4) + 1 + (ssMelees[expsys[0].Name] / 16);
                                if (ship.X > sstarget.X) expval[0] = expsys[0].X + meleerange;
                                else expval[0] = expsys[0].X - meleerange;
                                if (ship.Y > sstarget.Y) expval[1] = expsys[0].Y + meleerange;
                                else expval[1] = expsys[0].Y - meleerange;
                                Move(ship, expval[0], expval[1]);
                            }
                        }
                        else
                        {
                            //Fleet Wars!
                            shtarget = ClosestStarShip(ship.X, ship.Y, 32767, FindShipFlags.Enemy, ShipKnownFlags.Either);
                            if (shtarget != null)
                            {
                                Move(ship, shtarget.X, shtarget.Y);
                            }
                            else
                            {
                                Move(ship, (int)fleetpoint.X, (int)fleetpoint.Y);
                            }
                        }
                    }
                    #endregion

                    //My Startillery Order Code
                    #region Startillery Order Code
                    if ((ship.ShipType == StarShipType.StarTillery) | (ship.ShipType == StarShipType.ScanShip) | (ship.ShipType == StarShipType.SpyShip))
                    {
                        shtarget = ClosestStarShip(ship.X, ship.Y, (ship.Value * 2) + 1, FindShipFlags.Enemy, ShipKnownFlags.Either);
                        sstarget = ClosestStarSystem(ship.X, ship.Y, 32767, FindSystemFlags.Unfriendly);
                        PulsarInfo pm = null;
                        if (ship.IsDamaged == true)
                        {
                            pm = ClosestPulsar(ship.X, ship.Y, 32767);
                        }

                        if (pm != null)
                        {
                            Move(ship, pm.X, pm.Y);
                        }
                        else if (shtarget != null)
                        {
                            int range = ship.Value - 1;
                            int mx = Math.Abs(ship.X - shtarget.X);
                            int my = Math.Abs(ship.Y - shtarget.Y);
                            mx = mx * mx;
                            my = my * my;
                            int z = (int)Math.Sqrt(mx + my);

                            if (range < 5) range = 5;
                            if (z < 1) z = 1;
                            double dbuf = ((double)z / (double)range);
                            double dbufx = ((double)ship.X - (double)shtarget.X);
                            double dbufy = ((double)ship.Y - (double)shtarget.Y);
                            if (dbuf <= 0) dbuf = 0.001;
                            int Diffx = (int)Math.Floor(dbufx / dbuf);
                            int Diffy = (int)Math.Floor(dbufy / dbuf);

                            Move(ship, shtarget.X + Diffx, shtarget.Y + Diffy);
                        }
                        else if ((zerostars == false) & (sstarget != null))
                        {
                            //defend my stars or allied stars
                            expval[0] = 32768;
                            expsys[0] = null;
                            for (int ad = 0; ad < ssTeamStarSystem.Count; ad++)
                            {
                                sys = ssTeamStarSystem[ad];
                                sysval = DistanceQuick(sstarget.X, sstarget.Y, sys.X, sys.Y);
                                if ((sysval < expval[0]) & (sys.Scanners >= ship.Value - 2))
                                {
                                    expsys[0] = sys;
                                    expval[0] = sysval;
                                }
                            }
                            if (expsys[0] != null)
                            {
                                ssMelees[expsys[0].Name]++;
                                meleerange = (ship.Value / 4) + 1 + (ssMelees[expsys[0].Name] / 16);
                                if (ship.X > sstarget.X) expval[0] = expsys[0].X + meleerange;
                                else expval[0] = expsys[0].X - meleerange;
                                if (ship.Y > sstarget.Y) expval[1] = expsys[0].Y + meleerange;
                                else expval[1] = expsys[0].Y - meleerange;
                                Move(ship, expval[0], expval[1]);
                            }
                        }
                        else
                        {
                            //Fleet Wars!
                            Move(ship, (int)fleetpoint.X, (int)fleetpoint.Y);
                        }
                    }
                    #endregion

                }
                #endregion
                //debugstring = "Error : Build Starships";
                #region Build Starships
                int eshipdist = 32767;
                int estardist = 32767;
                int xf = 0;
                int expeng = wareng2;
                int scapital = 0;
                for (int d = 0; d < ssMyStarSystem.Count; d++)
                {
                    sys = ssMyStarSystem[d];
                    if (sys.AutoStarShip == true) SetAutoStarShip(sys, false);
                    if (sys.AutoShields == true) SetAutoShields(sys, false);

                    sstarget = ClosestStarSystem(sys.X, sys.Y, 32767, FindSystemFlags.Unfriendly);
                    shtarget = ClosestStarShip(sys.X, sys.Y, 32767, FindShipFlags.Enemy, ShipKnownFlags.Either);
                    if (shtarget != null) eshipdist = DistanceQuick(sys.X, sys.Y, shtarget.X, shtarget.Y);
                    if (sstarget != null) estardist = DistanceQuick(sys.X, sys.Y, sstarget.X, sstarget.Y);

                    if (sys.Resources > 210) expeng = wareng4;
                    else if (sys.Resources >= 70) expeng = wareng3;
                    else expeng = wareng2;

                    if ((sys != mycap) | (knownstarshields < 15))
                    {
                        if ((estardist <= 20) & (expeng <= wareng2)) expeng = wareng2;
                    }
                    else
                    {
                        if ((estardist <= 20) & (expeng <= wareng3)) expeng = wareng2;
                    }
                    if ((expeng == wareng2) & (estardist >= 40)) expeng = wareng3;
                    if ((expeng == wareng3) & (estardist >= 90)) expeng = wareng4;

                    if (sys == mycap)
                    {
                        #region Capital Build Code
                        scapital = ((sys.Value / 10) + (int)(TechMultiple * 2) + 6);
                        scapital = scapital - sys.Shields;
                        if (scapital > 0) BuildShields(sys, scapital);

                        if ((closecombatbattle == true) & (sys.Resources >= 100) & (IsMultiPlayerGame == false) & (numplayers == 2))
                        {
                            if (ecap.X > mycap.X) xf = 0;
                            else if (ecap.X == mycap.X) xf = 3;
                            else xf = 5;
                            if (ecap.Y < mycap.Y && xf != 3) xf = xf + 2;
                            else if (ecap.Y < mycap.Y && xf == 3) xf = xf + 1;
                            else if (ecap.Y == mycap.Y) xf = xf + 1;

                            for (int ad = 0; ad < 8; ad++)
                            {
                                if ((ad >= xf - 1) & (ad <= xf + 1))
                                {
                                    BuildStarShip(sys, StarShipType.WarShip, wareng3, 5, cloaker);
                                }
                                else
                                    BuildStarShip(sys, StarShipType.EMine, 1, 0, cloaker);
                            }
                        }
                        else if (eshipdist < 7 + (int)(TechMultiple))
                        {
                            if (closecombatbattle == false)
                            {
                                for (int ad = 1; ad <= 4; ad++)
                                    BuildStarShip(sys, StarShipType.EMine, 1, 0, cloaker);
                                SetAutoStarShipType(sys, StarShipType.Drone, wareng1, 0, cloaker);
                            }
                            else
                            {
                                SetAutoStarShipType(sys, StarShipType.WarShip, wareng1, Random(2,3), cloaker);
                            }
                            SetAutoStarShip(sys, true);
                        }
                        else if (sys.Resources >= 2400)
                        {
                            for (int ad = 1; ad <= 4; ad++)
                            {
                                BuildStarShip(sys, StarShipType.CommandShip, 20, 12, true);
                                BuildStarShip(sys, StarShipType.StarTillery, 20, 12, true);
                            }
                            SetAutoStarShipType(sys, StarShipType.WarShip, 20, 15, true);
                            SetAutoStarShip(sys, true);
                        }
                        else if (sys.Resources >= 990)
                        {
                            for (int ad = 1; ad <= 2; ad++)
                            {
                                BuildStarShip(sys, StarShipType.HijackShip, 12, 0, cloaker);
                                BuildStarShip(sys, StarShipType.CommandShip, 20, 12, cloaker);
                                BuildStarShip(sys, StarShipType.StarTillery, 20, 12, cloaker);
                                BuildStarShip(sys, StarShipType.HijackShip, 12, 0, cloaker);
                            }
                            SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(5, 8), cloaker);
                            SetAutoStarShip(sys, true);
                        }
                        else if (sys.Resources >= 110)
                        {
                            for (int ad = 1; ad <= 4; ad++)
                            {
                                BuildStarShip(sys, StarShipType.HijackShip, 12, 0, cloaker);
                            }
                            SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(5, 7), cloaker);
                            SetAutoStarShip(sys, true);
                        }
                        else if ((expand == true) | (estardist <= 12))
                        {
                            SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(4, 6), cloaker);
                            SetAutoStarShip(sys, true);
                            if (uuEMine.Count < 2) BuildStarShip(sys, StarShipType.EMine, 1, 0, cloaker);
                        }
                        else if (uuEMine.Count < 2)
                        {
                            SetAutoStarShipType(sys, StarShipType.EMine, 1, 0, cloaker);
                            SetAutoStarShip(sys, true);
                        }
                        else if (TechMultiple <= 3.0)
                        {
                            SetAutoStarShipType(sys, StarShipType.TechShip, 3, 0, cloaker);
                            SetAutoStarShip(sys, true);
                        }
                        else if (uuEMine.Count <= ssTeamStarSystem.Count * 8)
                        {
                            SetAutoStarShipType(sys, StarShipType.EMine, 1, 0, cloaker);
                            SetAutoStarShip(sys, true);
                        }
                        else
                        {
                            SetAutoStarShipType(sys, StarShipType.TechShip, 3, 0, cloaker);
                            SetAutoStarShip(sys, true);
                        }
                        #endregion
                    }
                    else
                    {
                        if (sys.Value >= 12)
                        {
                            #region HighValue Star
                            if ((eshipdist <= 2 + (int)(TechMultiple / 2)) & (sys.Resources <= 10))
                            {
                                SetAutoShields(sys, true);
                                SetAutoStarShipType(sys, StarShipType.Drone, wareng1, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (eshipdist < 5 + (int)(TechMultiple))
                            {
                                for (int ad = 0; ad < 8; ad++) BuildStarShip(sys, StarShipType.EMine, 1, 0, cloaker);
                                SetAutoStarShipType(sys, StarShipType.Drone, wareng2, 0, cloaker);
                                SetAutoStarShip(sys, true);
                                SetAutoShields(sys, true);
                            }
                            else if ((expand == true) | (estardist <= 15))
                            {
                                SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(4, 6), cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (uuHijackShip.Count <= ssTeamStarSystem.Count * (int)(TechMultiple * 0.5 + 1.5))
                            {
                                SetAutoStarShipType(sys, StarShipType.HijackShip, expeng, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if ((int)(TechMultiple * 5) > uuCommandShip.Count)
                            {
                                SetAutoStarShipType(sys, StarShipType.CommandShip, 20, 10, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if ((int)(TechMultiple) > uuWarShip.Count)
                            {
                                SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(4, 7), cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if ((int)(TechMultiple * 15) > uuEMine.Count)
                            {
                                SetAutoStarShipType(sys, StarShipType.EMine, 1, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else
                            {
                                SetAutoStarShipType(sys, StarShipType.TechShip, 3, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            #endregion
                        }
                        else
                        {
                            #region LowValue Star
                            if ((eshipdist <= 3 + (int)(TechMultiple / 2)) & (sys.Resources <= 10))
                            {
                                SetAutoShields(sys, true);
                                SetAutoStarShipType(sys, StarShipType.Drone, wareng1, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (eshipdist < 11 + (int)(TechMultiple))
                            {
                                for (int ad = 0; ad < 8; ad++) BuildStarShip(sys, StarShipType.EMine, 1, 0, cloaker);
                                SetAutoStarShipType(sys, StarShipType.Drone, wareng2, 0, cloaker);
                                SetAutoStarShip(sys, true);
                                SetAutoShields(sys, true);
                            }
                            else if ((expand == true) | (estardist <= 30) | (uuWarShip.Count < ssTeamStarSystem.Count))
                            {
                                SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(4, 5), cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (uuHijackShip.Count <= ssTeamStarSystem.Count * 3)
                            {
                                SetAutoStarShipType(sys, StarShipType.HijackShip, expeng, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (TechMultiple <= 8.0)
                            {
                                SetAutoStarShipType(sys, StarShipType.TechShip, 3, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (uuHijackShip.Count <= ssTeamStarSystem.Count * 15)
                            {
                                SetAutoStarShipType(sys, StarShipType.HijackShip, expeng, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (uuEMine.Count <= ssTeamStarSystem.Count * 8)
                            {
                                SetAutoStarShipType(sys, StarShipType.EMine, expeng, 0, cloaker);
                                SetAutoStarShip(sys, true);
                            }
                            else if (uuHijackShip.Count > uuWarShip.Count * 2)
                            {
                                SetAutoStarShipType(sys, StarShipType.WarShip, expeng, Random(4, 6), cloaker);
                                SetAutoStarShip(sys, true);
                            }

                            #endregion
                        }
                    }
                }
                #endregion
            }
            catch
            {
                //MessageBox.Show(ex.ToString() + " ==> " + debugstring);
            }
        }

        #region Custom Methods
        public bool IsPositive(string message)
        {
            message = message.ToLower();
            if ((message == "yep") | (message == "yes") | (message == "ok") |
                (message == "k") | (message == "yeppers") | (message == "sure") |
                (message == "yeah") | (message == "go") | (message == "accepted") |
                (message == "good") | (message == "accept") | (message == "si") |
                (message == "always") | (message == "we") | (message == "yea") |
                (message == "do") | (message == "fine") | (message == "10-4") |
                (message == "yes,"))
                return true;
            else
                return false;
        }

        public bool IsNegative(string message)
        {
            message = message.ToLower();
            if ((message == "nope") | (message == "no") | (message == "never") |
                (message == "nok") | (message == "not") | (message == "naw") |
                (message == "nay") | (message == "stop") | (message == "unaccepted") |
                (message == "bad") | (message == "declined") | (message == "don't") |
                (message == "no,"))
                return true;
            else
                return false;
        }

        public void BreakDownMessageIntoWords(string message, List<string> output)
        {
            string[] tmpstr;
            string[] sepr = new string[1];

            sepr[0] = " ";

            tmpstr = message.Split(sepr, StringSplitOptions.RemoveEmptyEntries);

            for (int ad = 0; ad < tmpstr.Length; ad++)
                output.Insert(ad, tmpstr[ad]);
        }

        public bool IsMessageAdressedToMe(string myname, string message)
        {
            int lengthofmyname = 0;
            int lengthofmessage = 0;
            message = message.ToLower();
            myname = myname.ToLower();
            lengthofmyname = myname.Length;
            lengthofmessage = message.Length;
            if (lengthofmyname < lengthofmessage)
            {
                if (message.Substring(lengthofmyname, 1) == ",")
                {
                    if (message.Substring(0, lengthofmyname) == myname)
                        return true;
                    else
                        return false;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        public bool IsFullAlliance(string dPlayerName)
        {
            if ((AlliedWithMe(dPlayerName) != AllianceLevel.None) & (AlliedWith(dPlayerName) != AllianceLevel.None))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool IsAdjacentToCoords(StarShipInfo ship, int cX, int cY)
        {
            int x = cX;
            int y = cY;
            if (ship.X >= x - 1 && ship.Y >= y - 1 && ship.X <= x + 1 && ship.Y <= y + 1)
                return true;

            return false;
        }

        private WormholeInfo WormHoleWayFaster(StarShipInfo thisSS, int destx, int desty)
        {
            WormholeInfo TWormhole = null;
            int diffx = 0;
            int diffy = 0;
            int directdistance = 0;
            int altdistance1 = 0;
            int altdistance2 = 0;
            int closesttodest = 32767;
            foreach (WormholeInfo whinfo in Wormholes)
            {
                if (whinfo.DestinationKnown == true)
                {
                    diffx = Math.Abs(thisSS.X - destx);
                    diffy = Math.Abs(thisSS.Y - desty);
                    if (diffx > diffy) directdistance = diffx;
                    else directdistance = diffy;
                    diffx = Math.Abs(thisSS.X - whinfo.X);
                    diffy = Math.Abs(thisSS.Y - whinfo.Y);
                    if (diffx > diffy) altdistance1 = diffx;
                    else altdistance1 = diffy;
                    diffx = (int)Math.Abs(destx - whinfo.Destination.X);
                    diffy = (int)Math.Abs(desty - whinfo.Destination.Y);
                    if (diffx > diffy) altdistance2 = diffx;
                    else altdistance2 = diffy;

                    if ((directdistance - (thisSS.Engines / 2) >= altdistance1 + altdistance2) & (closesttodest > altdistance1 + altdistance2))
                    {
                        closesttodest = altdistance1 + altdistance2;
                        TWormhole = whinfo;
                    }
                }
            }
            return TWormhole;
        }

        private WormholeInfo ClosestWormhole(int x, int y, int maxdistance, bool destknown)
        {
            WormholeInfo TWormhole = null;
            int diffx = 0;
            int diffy = 0;
            int ddistance = 0;
            int dclosest = maxdistance;
            foreach (WormholeInfo whinfo in Wormholes)
            {
                if (whinfo.DestinationKnown == destknown)
                {
                    diffx = Math.Abs(x - whinfo.X);
                    diffy = Math.Abs(y - whinfo.Y);
                    ddistance = diffx + diffy;
                    if (ddistance < dclosest)
                    {
                        dclosest = ddistance;
                        TWormhole = whinfo;
                    }
                }
            }
            return TWormhole;
        }

        public void AllianceSet(string playername)
        {
            for (int d = 0; d < PlayerNames.Count; d++)
            {
                if (PlayerNames[d] == playername)
                    justallied[d] = true;
            }
        }

        public void AllianceBroke(string playername)
        {
            for (int d = 0; d < PlayerNames.Count; d++)
            {
                if (PlayerNames[d] == playername)
                    justallied[d] = false;
            }
        }

        #endregion

    }
}
